/* Para que ande el strnlen */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif /*_GNU_SOURCE*/

#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
#include "data.h"
#include "bool.h"

struct sdata
{
  char *dat;
};


data 
data_empty(void)
{
  
  data res;
  
  res=(data)malloc(sizeof(struct sdata));
  
  if (res != NULL)
    {
      res->dat = NULL;
    }
  
  return res;
  
}

/*
  DESC: Construye un dato vacio. 
  PRE: { True }
  d = data_empty();
  POS: {  Hay memoria ==> d --> empty 
  ! Hay memoria ==> d == NULL }
*/

data 
data_destroy(data d)
{
  
  if ((d->dat)!=NULL)
  	{
	free(d->dat);
  	(d->dat)=NULL;
  	}  

  free(d);
  d=NULL;
  return d;
}

/*
  DESC: Destructor del tipo. d cambia.
  PRE: { d --> D }
  d = data_destroy(d);
  POS: { Se destruye D /\ d == NULL }
*/


bool 
data_copyStr(data d,const char *s)
{
  
  bool b=FALSE;
  
  d->dat=(char*)realloc(d->dat,(strlen(s)+1)*sizeof(char));
  
	
  if (d->dat != NULL ) 
    {
     
      d->dat=strcpy(d->dat,s);
      b=TRUE;
    }
  
  
  return b;
}

/*
  DESC: Transforma el string en dato y lo copia d. 
  Devuelve False si no hay memoria.
  PRE: { d --> D /\ s --> S }
  b = data_copyStr(d,s);  
  POS: {  Hay memoria ==>  b /\ d --> fromStr(S)   
  ! Hay memoria ==> !b /\ d --> D }   
*/


char *
data_toStr(const data d)
{
  char *s; /*ver*/
  assert(d->dat != NULL);
  
  s=(char*)malloc(sizeof(char)*(strlen(d->dat)+1));
  
  if (s!=NULL)
    {
      s=strcpy(s,d->dat);
    }
  
  return s;
  
}

/*
  DESC: Devuelve un nuevo string (despues de usarlo hay que liberarlo) que 
  representa al dato. 
  PRE: { d --> D  /\ s = NULL }
  s = data_toStr(d);
  POS: {   Hay memoria ==> s --> toStr(S)  
  ! Hay memoria ==> s == NULL  }
*/


data 
data_clone(const data d)
{

  data dd=NULL;
  
  assert(d->dat!=NULL);
  
  dd=data_empty();
  data_copyStr(dd,d->dat);
  
  return dd;
}

/*
  DESC: Construye una copia.
  PRE: { d1 --> D1 /\ d2 = NULL }
  d2 = data_clone(d1);  
  POS: {  Hay memoria ==> d1 --> D1 /\ d2 --> D1 /\ d1 != d2 
  ! Hay memoria ==> d2 == NULL /\ d1 --> D1 }   
*/
